package com.bhf.utils;

import com.bhf.core.JwtAuthConfigs;
import com.bhf.model.entity.CustomUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author pwq
 */
@Component
public class JwtTokenManager {
    private static final String AUTHORITIES_KEY = "auth";

    @Resource
    private JwtAuthConfigs authConfigs;

    /**
     * Create token.
     *
     * @param authentication auth info
     * @return token
     */
    public String createToken(Authentication authentication) {
        CustomUser principal = (CustomUser)authentication.getPrincipal();
        return createToken(principal.getUsername(),principal.getId());
    }

    /**
     * Create token.
     *
     * @param userName auth info
     * @return token
     */
    public String createToken(String userName,long id) {
        long now = System.currentTimeMillis();
        Date validity;
        validity = new Date(now + authConfigs.getExpireTime() * 1000L);
        Claims claims = Jwts.claims().setSubject(userName);
        return Jwts.builder().setClaims(claims).setExpiration(validity).setId(String.valueOf(id))
                .signWith(Keys.hmacShaKeyFor(authConfigs.getSecretKeyBytes()), SignatureAlgorithm.HS256).compact();
    }

    /**
     * Get auth Info.
     *
     * @param token token
     * @return auth info
     */
    public Authentication getAuthentication(String token) {
        Claims claims = Jwts.parserBuilder().setSigningKey(authConfigs.getSecretKeyBytes()).build()
                .parseClaimsJws(token).getBody();
        List<GrantedAuthority> authorities = AuthorityUtils
                .commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
        CustomUser principal = new CustomUser(Long.valueOf(claims.getId()), claims.getSubject(), "", authorities);
        return new UsernamePasswordAuthenticationToken(principal, "", authorities);
    }

    /**
     * validate token.
     *
     * @param token token
     */
    public void validateToken(String token) {
        Jwts.parserBuilder().setSigningKey(authConfigs.getSecretKeyBytes()).build().parseClaimsJws(token);
    }
}
